package com.gaogzhen.service.impl;

import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.gaogzhen.feign.OAuth2FeignClient;
import com.gaogzhen.geetest.GeetestLib;
import com.gaogzhen.model.JwtToken;
import com.gaogzhen.model.LoginForm;
import com.gaogzhen.model.LoginUser;
import com.gaogzhen.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @version 1.0
 * @description
 * @date 2022-07-05 11:09
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private GeetestLib geetestLib;


    /**
     * 会员登录
     * @param loginForm 登录表单参数
     * @return          登录成功的用户
     */
    @Override
    public LoginUser login(LoginForm loginForm) {

        // 校验登录表单
        checkFormData(loginForm);
        // 登录->获取token
        // 远程调用
        ResponseEntity<JwtToken> tokenResponseEntity = oAuth2FeignClient.getToken("password", loginForm.getUsername(), loginForm.getPassword(), "member_type", basicToken);
        if (tokenResponseEntity.getStatusCode() != HttpStatus.OK) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = tokenResponseEntity.getBody();
        // 返回前端token包含bearer
        LoginUser loginUser = new LoginUser(loginForm.getUsername(), jwtToken.getExpiresIn(), jwtToken.getTokenType() + " " +jwtToken.getAccessToken(), jwtToken.getRefreshToken());

        // 使用网关解决登出问题，redis存储
        redisTemplate.opsForValue().set(jwtToken.getAccessToken(), "", jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        return loginUser;
    }

    /**
     * 校验登录表单
     * @param loginForm 登录表单
     */
    private void checkFormData(LoginForm loginForm) {
        loginForm.authenticate(geetestLib, redisTemplate);
    }
}
